package cn.jdemo.ref.WeakReference;

import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.HashMap;

/**
 * @see WeakReference
 * @see WeakReference#WeakReference(Object) 指定对象object作为弱引用
 * @see WeakReference#WeakReference(Object, ReferenceQueue)
 *
 * @see WeakReference#get() 获取传入的指定对象，若被回收，则返回null
 *
 * @date 2021/1/8
 */
public class Demo01 {
    public static void main(String[] args) {
        test00();
    }

    /**
     * 输出内容:
     * ... ...
     * cn.jdemo.ref.WeakReference.A@61a1ea2c : cn.jdemo.ref.WeakReference.B@54f4a7f0
     * Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
     */
    public static void test00() {
        // a是对象A的引用，b是对象B的引用，对象B同时还依赖对象A
        HashMap map = new HashMap<B,A>();
        for (;;){
            A a = new A();
            B b = new B(a);
            map.put(b,a);
            System.out.println(a+" : "+b);
        }
    }

    /**
     * 输出内容:
     * ... ...
     * exit:java.lang.ref.WeakReference@4141d797
     * exit:java.lang.ref.WeakReference@4141d797
     * exit:java.lang.ref.WeakReference@4141d797
     * notexit:null
     */
    public static void test03() {
        WeakReference<B> weakReference = new WeakReference<B>(new B());
        for (;;){
            if (weakReference.get()!=null){
                System.out.println("exit:"+weakReference);
            }else{
                System.out.println("notexit:"+weakReference.get());
                break;
            }
        }
    }

    /**
     * 输出内容:
     * ... ...
     * exit:java.lang.ref.WeakReference@4141d797
     * exit:java.lang.ref.WeakReference@4141d797
     * exit:java.lang.ref.WeakReference@4141d797
     * notexit:null
     */
    public static void test04() {
        WeakReference<B> weakReference = new WeakReference<B>(new B(),new ReferenceQueue<B>());
        for (;;){
            if (weakReference.get()!=null){
                System.out.println("exit:"+weakReference);
            }else{
                System.out.println("notexit:"+weakReference.get());
                break;
            }
        }
    }

    /**
     * string不会被回收
     */
    public static void test01() {
        String ref = new String("ref");
        WeakReference<String> weakReference = new WeakReference<String>(ref, new ReferenceQueue<String>());
        for (;;){
            if (weakReference.get()!=null){
                System.out.println("exit:"+weakReference);
            }else{
                System.out.println("notexit:"+weakReference.get());
                break;
            }
        }
    }

    /**
     * string不会被回收
     */
    public static void test02() {
        String ref = new String("ref");
        WeakReference<String> weakReference = new WeakReference<String>(ref);
        for (;;){
            if (weakReference.get()!=null){
                System.out.println("exit:"+weakReference);
            }else{
                System.out.println("notexit:"+weakReference.get());
                break;
            }
        }
    }
}

class A{

}

class B{
    A a;
    B(){}
    B(A a){ this.a=a; }
}
